package com.my12306.train.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.my12306.common.constant.CommonConstants;
import com.my12306.common.enums.CodeEnum;
import com.my12306.common.util.PageUtils;
import com.my12306.common.util.SnowflakeIdWorker;
import com.my12306.common.util.response.ResponseData;
import com.my12306.train.constant.TrainConstant;
import com.my12306.train.dao.SeatDao;
import com.my12306.train.model.entity.SeatEntity;
import com.my12306.train.model.vo.PageSeatVo;
import com.my12306.train.service.SeatService;
import com.my12306.train.utils.TrainUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

/**
 * @Author:苏牧夕
 * @Date:2020/8/27 9:25
 * @Version 1.0
 */
@Slf4j
@Service("seatService")
public class SeatServiceImpl extends ServiceImpl<SeatDao, SeatEntity> implements SeatService {



    /**
     * 方法作用： 定时任务 刷新每天的席位信息
     * 1. 查出当前所有的席位信息
     * 2. 把当天的所有席位信息修改为逻辑删除状态
     * 3. 把当前的所有席位信息的时间修改为三天后添加一份
     */
    @Override
    @Transactional
    public void refreshSeatEveryDay() {
        log.info("=====================》开始定时任务咯");
        //1. 查出当前所有的席位信息
        List<SeatEntity> seatEntities = this.querySeatsByToDay();
        log.info("============>当天的席位信息："+seatEntities);
        //2. 把当天的所有席位信息修改为逻辑删除状态
        List<Long> ids = seatEntities.stream().map(x -> {
            return x.getSeatId();
        }).distinct().collect(Collectors.toList());
        log.info("==============>需要清除的席位信息："+ids);
        this.removeSeatByIds(ids);
        //3. 把当前的所有席位信息的时间修改为三天后添加一份
        this.savaSeatsByToDay(seatEntities, 3);
        log.info("=============>定时任务结束");
    }

    /**
     * 把当前的数据时间修改为三天后的
     * 1. 根据车次代码 找出车次的默认终点站
     * 2. 把其实站修改为初始化记录的站点
     *
     * @param seatEntities
     */
    private void savaSeatsByToDay(List<SeatEntity> seatEntities, int dateNumber) {
        AtomicBoolean isError = new AtomicBoolean(false);
        List<SeatEntity> result = seatEntities.stream().map(item -> {
            item.setCreateDate(new Date());
            item.setUpdateDate(new Date());
            item.setSeatId(SnowflakeIdWorker.generateId());
            String initStation = item.getInitStation();
            Date startDate = item.getStartDate();
            log.info("initStation="+initStation+",startDate="+startDate);
            if (initStation!=null&&startDate!=null) {
                item.setSeatStatus(TrainConstant.SEATE_NOT_SOLD);
                SimpleDateFormat instance = new SimpleDateFormat(TrainUtils.dateStr);
                String format = instance.format(startDate);
                item.setStartDate(TrainUtils.caclet(format, TrainUtils.formate, dateNumber));
                String[] split = initStation.split("-");
                log.info(split[0]+","+split[1]);
                log.info("len="+split.length);
                if (split.length>1) {
                    item.setStartStation(split[0]);
                    item.setEndStation(split[1]);
                }else{
                    isError.set(true);
                    return null;
                }
            }else{
                isError.set(true);
                return null;
            }

            return item;
        }).filter(x->{return x!=null;}).distinct().collect(Collectors.toList());
        log.info("================>添加后三天的数据信息："+result);
        if (isError.get()){
            log.error("===========>数据刷新异常："+new Date()+",数据集"+seatEntities);
        }
        if (result!=null&&result.size()>0) {
            this.baseMapper.saveBatchSeats(result);

        }
      log.info("==================>添加后三天数据信息完成！！");
    }

    /**
     * 查询当天的所有数据
     *
     * @return
     */
    private List<SeatEntity> querySeatsByToDay() {
        LocalDateTime currDate = LocalDateTime.now();
        String toDay = currDate.format(TrainUtils.formate);//今天的时间
        String beforeDay = currDate.plusDays(-1).format(TrainUtils.formate);//昨天的时间
        Date oneTime = TrainUtils.caclet(toDay, TrainUtils.formate, 0);
        Date twoTime = TrainUtils.caclet(beforeDay, TrainUtils.formate, 0);
        log.info("查询条件："+oneTime+",endTime:"+twoTime+",now："+new Date());
        return this.baseMapper.querySeatsByToDay(twoTime, oneTime, CommonConstants.LogicDelete.no_delet.getValue());

    }

    /**
     * 批量移除
     *
     * @param seatIds
     * @return
     */
    @Override
    public ResponseData removeSeatByIds(List<Long> seatIds) {
        if (seatIds != null && seatIds.size() > 0) {
            this.baseMapper.updateBatchSeatBySeatIds(seatIds, CommonConstants.LogicDelete.delete.getValue());
            return ResponseData.ok();
        }

        return ResponseData.fail(CodeEnum.ADD_FAIL.getCode(), "删除失败！原因：数据不能为空！");
    }

    /**
     * 根据ID修改
     *
     * @param seat
     * @return
     */
    @Override
    public ResponseData updateSeatById(SeatEntity seat) {
        if (seat != null && seat.getSeatId() != null) {
            seat.setUpdateDate(new Date());
            this.baseMapper.updateById(seat);
            return ResponseData.ok();
        }
        return ResponseData.fail(CodeEnum.ADD_FAIL.getCode(), "添加失败！，原因:添加的数据不能为空！");
    }

    @Override
    public ResponseData saveSeat(SeatEntity seat) {
        if (seat != null) {
            seat.setCreateDate(new Date());
            seat.setUpdateDate(new Date());
            seat.setSeatId(SnowflakeIdWorker.generateId());
            seat.setSeatStatus(TrainConstant.SEATE_NOT_SOLD);
            this.baseMapper.insert(seat);
            return ResponseData.ok();
        }
        return ResponseData.fail(CodeEnum.ADD_FAIL.getCode(), "添加失败！，原因:添加的数据不能为空！");
    }

    @Override
    public Boolean saveBatchSeat(List<List<SeatEntity>> seatEntities) {
         if (seatEntities!=null&&seatEntities.size()>0){
             List<SeatEntity> result = new ArrayList<>();
             seatEntities.stream().forEach(x->{
                 result.addAll(x);
             });
                 if (result != null && result.size() > 0) {
                     this.baseMapper.saveBatchSeats(result);
                     return true;
                 }else{
                     return false;
                 }
         }
        return false;
    }

    /**
     * 根据id 查询席位信息
     *
     * @param seatId
     * @return
     */
    @Override
    public SeatEntity getSeatById(Long seatId) {
        if (seatId != null) {
            return this.baseMapper.selectById(seatId);
        }
        return null;
    }

    /**
     * 分页查询
     *
     * @param pageVo
     * @return
     */
    @Override
    public PageUtils querySeatsByPage(PageSeatVo pageVo) {
        pageVo.init();
        List<SeatEntity> dataList = this.baseMapper.querySeatsByPage(pageVo, CommonConstants.LogicDelete.no_delet.getValue());
        System.out.println(pageVo);
        int totalCount = this.querySeatsCountByPage(pageVo, CommonConstants.LogicDelete.no_delet.getValue());
        PageUtils pageUtils = PageUtils.build(pageVo, dataList, totalCount);
        return pageUtils;
    }

    /**
     * 检索是否已经生成过改车次的席位信息
     * @param trainCode
     * @return
     */
    @Override
    public List<SeatEntity> querySeatsByTrainCode(String trainCode) {
        if (trainCode!=null){
            QueryWrapper<SeatEntity> qw = new QueryWrapper<>();
            qw.eq("train_code",trainCode);
         return    this.baseMapper.selectList(qw);
        }
        return null;
    }

    @Override
    public List<Date> queryAllSeatsDate() {
      return  this.baseMapper.queryAllSeatDate(CommonConstants.LogicDelete.no_delet.getValue());
    }


    @Override
    public List<SeatEntity> querySeateByStartDate(String startDate, String trainCode, Integer sold, Integer logicDelete) {

        return null;
    }

    @Override
    public List<SeatEntity> querySeateByStartDateAndTrainCode(String strDate, List<String> trainCodes, Integer seateNotSold, String fromStation, Integer logicDelete) {
        if (strDate!=null&&trainCodes!=null&&trainCodes.size()>0&&seateNotSold!=null&&fromStation!=null&&logicDelete!=null){
            return this.baseMapper.querySeateByStartDateAndTrainCode(strDate,trainCodes,seateNotSold,fromStation,logicDelete);
        }
        return null;
    }

    @Override
    public List<SeatEntity> queryTicketSeateByStartDateAndTrainCode(String strDate, List<String> trainCode, Integer seateNotSold, String fromStation, Integer logicDelete) {
        if (strDate!=null&&trainCode!=null&&trainCode.size()>0&&seateNotSold!=null&&fromStation!=null&&logicDelete!=null){
            return this.baseMapper.queryTicketSeatByStartDateAndTrainCode(strDate,trainCode,seateNotSold,fromStation,logicDelete);
        }
        return null;
    }


    @Override
    public void deleteBatchSeatsByTrainCodeAndCoachNumber(List<String> trainCodes,List<Long> coachNumbers,int logicDelete,int showStatus) {
        if (trainCodes!=null&&trainCodes.size()>0&&coachNumbers!=null&&coachNumbers.size()>0){
            this.baseMapper.deleteBatchSeatsByTrainCodeAndCoachNumber(trainCodes,coachNumbers,logicDelete,showStatus);
        }
    }

    @Override
    public void updateBatchSeats(List<List<SeatEntity>> seatEntities) {
        log.error("==============修改："+seatEntities);
        if (seatEntities!=null&&seatEntities.size()>0) {
                List<SeatEntity> result = new ArrayList<>();
                seatEntities.stream().forEach(x->{
                    result.addAll(x);
                });
            List<Long> ids = result.stream().map(x -> {
                return x.getSeatId();
            }).distinct().collect(Collectors.toList());
            SeatEntity seatEntity = result.get(0);
            this.saveOrUpdateBatch(result,1000);
//            this.baseMapper.updateBatchSeate(seatEntity,ids);
        }
    }

    @Override
    public List<SeatEntity> querySeateSoledByTrainCodeAndStations(String strDate, String trainCode, List<String> stations, Integer seateSold, Integer logicDelete) {
        if (strDate!=null&&trainCode!=null&&stations!=null&&stations.size()>0&&seateSold!=null&&logicDelete!=null){
         return  this.baseMapper.querySeateSoledByTrainCodeAndStations(strDate,trainCode,stations,seateSold,logicDelete);
        }
        return null;
    }

    @Override
    public List<SeatEntity> queryTicketSeate(String strDate, String trainCode, List<String> stations, Integer seateSold, Integer logicDelete) {
        if (strDate!=null&&trainCode!=null&&stations!=null&&stations.size()>0&&seateSold!=null&&logicDelete!=null){
            return  this.baseMapper.queryTicketSeat(strDate,trainCode,stations,seateSold,logicDelete);
        }
        return null;
    }

    /**
     * 内置条件查询数据总量
     *
     * @param pageVo
     * @param logicDelete
     * @return
     */
    private Integer querySeatsCountByPage(PageSeatVo pageVo, Integer logicDelete) {
        if (pageVo == null || logicDelete == null) {
            return 0;
        }
        return this.baseMapper.querySeatsCountByPage(pageVo, logicDelete);
    }
//
//    public static void main(String[] args) {
//        DateTimeFormatter formate = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//
//        LocalDateTime currDate = LocalDateTime.now();
//        String toDay = currDate.format(formate);
//        String beforeDay = currDate.plusDays(-1).format(formate);
////        beforeDay = "2020-08-27 00:00:00";
////        toDay="2020-08-28 00:00:00";
//        Date oneTime = caclet(toDay, formate,0);
//        Date afterDay =  caclet(beforeDay,formate,0);
//
//        System.out.println("当天时间："+oneTime + ", 后一天时间："+afterDay);
//
////        LocalDateTime currDate = LocalDateTime.now();
////        DateTimeFormatter formate = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
////        String toDaty = currDate.format(formate);
////        String afterDay = currDate.plusDays(1).format(formate);
////        toDaty = "2020-08-27 09:30:00";
////        afterDay="2020-08-28 12:30:00";
////        Date oneTime = caclet(toDaty, formate,5);
////        Date twoTime =  caclet(afterDay,formate,0);
////        SimpleDateFormat instance = new SimpleDateFormat(dateStr);
////        String format = instance.format(oneTime);
////        System.out.println(caclet(format, formate, 3));
////        System.out.println("当天时间："+oneTime.toString() + ", 后一天时间："+twoTime.toString());
//    }

}
